#pragma once

#include <iostream>
#include <functional>
#include <string>
#include <pthread.h>

#include "Socket.hpp"

using func_t = std::function<std::string(std::string &, bool *error_code)>;

class TcpServer;

class ThreadDate
{
public:
    ThreadDate(TcpServer *tcp_this, Net_Work::Socket *sockp)
    : _this(tcp_this), _sockp(sockp)
    {}
public:
    TcpServer *_this;
    Net_Work::Socket *_sockp;
};

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t handler_request)
        : _port(port), _listensocket(new Net_Work::TcpSocket()), _handler_request(handler_request)
    {
        _listensocket->BuildListenSocketMethod(port, 5);
    }

    static void *ThreadRun(void *args)
    {
        // 分离线程
        pthread_detach(pthread_self());
        ThreadDate *td = static_cast<ThreadDate *>(args);

        // 读取数据，不关心数据是什么，只读取
        std::string inbufferstream;
        while(true)
        {
            bool ok = true;
            // 1.读取数据
            if(!td->_sockp->Recv(&inbufferstream, 1024))
                break;

            std::cout << "inbufferstream: " << inbufferstream << std::endl;

            // 2.报文处理
            std::string send_string = td->_this->_handler_request(inbufferstream, &ok);
            std::cout << "要发送的报文数据: " << send_string << std::endl;
            std::cout << "状态码: " << ok << std::endl; 
            if(ok)
            {
                // 3.发送数据，不关心数据是什么，只发送
                if(!send_string.empty())
                {
                    td->_sockp->Send(send_string);
                }
            }
            else
            {
                std::cout << "inbufferstream is empty" << std::endl;
                break;
            }

            sleep(1);
        }
        return nullptr;
    }

    void Loop()
    {
        while(true)
        {
            std::string peerip;
            uint16_t peerport;
            Net_Work::Socket *newsock = _listensocket->AcceptConnecttion(&peerip, &peerport);
            if(newsock == nullptr)
                continue;
            std::cout << "获取一个新链接， sockfd: " << newsock->GetSockfd() << "client info: " << peerip << ":" << peerport << std::endl;

            pthread_t tid;
            ThreadDate *td = new ThreadDate(this, newsock);
            pthread_create(&tid, nullptr, ThreadRun, (void *)td);
        }
    }
private:
    int _port;
    Net_Work::Socket *_listensocket;

public:
    func_t _handler_request;
};